﻿import mx.controls.ComboBox;

import flash.filters.DropShadowFilter;

import com.yourdomain.spreadshop.gui.GUI;
import com.yourdomain.spreadshop.gui.mod.lib.Module;
import com.yourdomain.spreadshop.gui.mod.lib.ScrollBar;
import com.yourdomain.spreadshop.gui.mod.lib.LoaderAnimation;

import net.spreadshirt.logger.Logger;

/**
 * The ItemsBoard class displays all article items.
 * The module owns a standard flash combobox componen
 * to switch the product type categories.
 */
class com.yourdomain.spreadshop.gui.mod.ItemsBoard {

	// The reference to the swf file.
	private static var _SWF:String = "spreadshop_itemsBoard.swf";

	// Various visual settings.
	private static var _POSITION:Object = { x: 8, y: 8 };
	private static var _LABEL_TITLE:String = "Produktauswahl";
	private static var _OPTION_ALL_PRODUCTS:String = "Alle Produkte";
	private static var _ROWS_PER_PAGE:Number = 4;
	private static var _COLS_PER_PAGE:Number = 4;
	private static var _ITEM_DISTANCE_X:Number = 112;
	private static var _ITEM_DISTANCE_Y:Number = 112;

	// The reference to the GUI main class. 
	private var _gui:GUI;

	// The movie clip container.
	private var _clip:MovieClip;

	// A variable that stores all the items
	// to support switching between the map and list view.
	private var _items:Array;

	// The view mode flag.
	private var _viewModeIsMap:Boolean;

	// Stores the id of the selected category.
	private var _catSelected_id:Number;

	/**
	 * ItemsBoard Constructor
	 */
	public function ItemsBoard(
		gui:GUI,
		clip:MovieClip,
		level:Number
	) {
		// Connects with the GUI instance.
		_gui = gui;
		// Create clip and set position on stage
		_clip = clip.createEmptyMovieClip("itemsBoard", level);
		// Create listener to watch loading in progress
		var mclListener:Object = new Object();
		mclListener.timer = [0, 0];
		mclListener.onLoadStart = function(target:MovieClip):Void {
		    this.timer[0] = getTimer();
		    Logger.getLog().info("GUI - ItemsBoard: start loading");
		};
		mclListener.onLoadComplete = function(target:MovieClip):Void  {
			this.timer[1] = getTimer();
		};
		mclListener.itemsBoard = this;
		mclListener.onLoadInit = function(target:MovieClip):Void  {
			var timer:Number = this.timer[1] - this.timer[0];
			var bytes:Number = target.getBytesLoaded();
			Logger.getLog().info("GUI - ItemsBoard: "+ bytes
				+" Bytes loaded in "+ timer +" ms.");
			this.itemsBoard.setup();
		};

		// Create loader an attach listener
		var mcLoader:MovieClipLoader = new MovieClipLoader();
		mcLoader.addListener(mclListener);
		mcLoader.loadClip(_gui.swf_path + _SWF, _clip);
	}

	/**
	 * Setup items board
	 */
	public function setup():Void {
		_gui.initModuleDone("initItemsBoard");
		// Create an alias to the items board movie clip.
		var clip:MovieClip = _clip.itemsBoard;
		// Setup modul.
		var module:Module = new Module(
			_gui,
			clip,
			false,
			_LABEL_TITLE,
			_POSITION.x,
			_POSITION.y
		);
		// Setup view mode.
		var modebts:MovieClip = clip.modebts;
		modebts.itemsBoard = this;
		modebts.setViewMode = function(mode:String):Void {
			if(mode == "map") {
				this.btmap._visible = false;
				this.btlist._visible = true;
			} else {
				this.btmap._visible = true;
				this.btlist._visible = false;
			}
			this.itemsBoard.setViewMode(mode);
			this.itemsBoard.showItems();
		};
		modebts.btmap.onPress = function():Void {
			this._parent.setViewMode("map");
		};
		modebts.btlist.onPress = function():Void {
			this._parent.setViewMode("list");
		};
		modebts.setViewMode("map");
	}

	/**
	 * Switch view mode
	 */
	public function setViewMode(mode:String):Void {
		if(mode == "map") {
			_viewModeIsMap = true;
		} else {
			_viewModeIsMap = false;
		}
	}

	/**
	 * Show categories
	 */
	public function showCategories(categoriesList:Array):Void {
		/**/for (var props:String in categoriesList){
			trace("categoriesList["+props+"]: "+categoriesList[props]);
			for (var subProps:String in categoriesList[props]){
				trace("\t categoriesList["+props+"]["+subProps+"]: "+ categoriesList[props][subProps]);
			}
		}
		// Create an alias to the items board movie clip.
		var board:MovieClip = _clip.itemsBoard;
		// Shows the items board movie clip.
		board.show();
		// Setup the categories combobox.
		board._lockroot = true;
		var catComboBox:ComboBox = board.categories;
		catComboBox.tabEnabled = false;
		// Creates the data provider for the combo box.
		var dataProvider:Array = new Array();
		// Sort the category items list.
		categoriesList.sortOn("weight", Array.NUMERIC);
		// Adds an option to view all products.
		dataProvider.push({
			data: -1,
			label: _OPTION_ALL_PRODUCTS
		});
		// Adds all categories.
		for(var i:Number = 0; i < categoriesList.length; i++) {
			var cat_id:Number = categoriesList[i].producttype_category_id;
			var names:Object = {
				singular: categoriesList[i].name,
				plural: categoriesList[i].name_plural
			};
			var isPlural:Boolean = true;
			dataProvider.push({
				data: cat_id,
				label: names[(isPlural) ? "plural" : "singular"]
			});
		}
		catComboBox.dataProvider = dataProvider;
		catComboBox.rowCount = categoriesList.length + 1;
		catComboBox.selectedIndex = 0;
		catComboBox.setStyle("color", "0x0099ff");
		catComboBox.setStyle("themeColor", "haloBlue");
		var catComboBoxListener:Object = new Object();
		catComboBoxListener.itemsBoard = this;
		//### JNF ##########################################################################################
		catComboBoxListener.change = function(evt:Object):Void {
			var category_id:Number = evt.target.selectedItem.data;
			this.itemsBoard._gui.showItemsByCategory(category_id);
		};
		catComboBox.addEventListener("change", catComboBoxListener);
		_catSelected_id = categoriesList[catComboBox.selectedIndex].data;
	}

	/**
	 * Create field of items.
	 */
	public function showItems(items:Array):Void {
		if(items == undefined) {
			items = _items;
		} else {
			_items = items;
		}
		// Create an alias to the item movie clip.
		var itms:MovieClip = _clip.itemsBoard.items.container;
		// Remove all items.
		for(var i:String in itms) {
			if(typeof itms[i] == "movieclip" && itms[i]._name != "item0") {
				itms[i].removeMovieClip();
			}
		}
		// Create new items.
		var row:Number = 0, col:Number = 0;
		for(var i:Number = 0; i < items.length; i++) {
			if(i > 0) {
				itms.item0.duplicateMovieClip("item"+ i, i);
			}
			var mc:MovieClip = itms["item"+ i];
			// Setup the picture movie clip. 
			mc.base.showTooltip = _viewModeIsMap;
			mc.base.itemsBoard = this;
			mc.base.onRollOver = function():Void {
				var pic:MovieClip = this._parent.pic;
				pic.isOver = true;
				pic.play();  
				var hi:MovieClip = this._parent.hi;
				hi.isOver = true;
				hi.play();
				if(this.showTooltip) {
					this.itemsBoard._gui.startTooltip(this.tooltip);
				}
			};
			mc.base.onRollOut = 
			mc.base.onDragOut = function():Void {
				var pic:MovieClip = this._parent.pic;
				pic.isOver = false;
				var hi:MovieClip = this._parent.hi;
				hi.isOver = false;
				if(this.showTooltip) {
					this.itemsBoard._gui.stopTooltip();
				}
			};
			mc.base.id = items[i].article_id;
			mc.base.onPress = function():Void {
				this.itemsBoard._gui.showItem(this.id);
			};

			// Setup the filter effects.
		    var filShadow:DropShadowFilter = Module.FILTER_SUB_SHADOW;
		    var filArray:Array = new Array();
		    filArray.push(filShadow);
		    mc.base.filters = filArray;
			// Enable caching.
			mc.cacheAsBitmap = true;

			// Check view mode.
			if(_viewModeIsMap) {
				// The map view mode.
				mc._x = _ITEM_DISTANCE_X * col++;
				mc._y = _ITEM_DISTANCE_Y * row;
				mc.info._visible = false;
				if(col % _COLS_PER_PAGE == 0) {
					row++;
					col = 0;
				}
				// The items data.
				var item:Object = items[i];
				// Setup tooltip data.
				mc.base.tooltip = item.name + "<br>"
					+"<b>"+ transformGross(item.gross)
					+" "+ item.currency +"</b>";
			} else {
				// The list view mode.
				mc._x = 0;
				mc._y = _ITEM_DISTANCE_Y * i;
				mc.info._visible = true;
				// Create an alias to the info movie clip.
				var info:MovieClip = mc.info;
				// The items data.
				var item:Object = items[i];
				// Setup info data.
				info.name.tf.text = item.name;
				info.description.tf.text = item.description;
				var sizes:Array = item.producttype_sizes.getAllItems();
				var strSizes:String = "";
				for(var s:Number = 0; s < sizes.length; s++) {
					strSizes += sizes[s].name;
					if((s + 1) < sizes.length) {
						strSizes += ", ";
					}
				}
				info.sizes.tf.text = strSizes;
				info.gross.tf.text = transformGross(item.gross);
				info.currency.tf.text = item.currency;
				// Hide the last separator lines.
				info.lines._visible = ((i + 1) < items.length);
				// Setup hit area.
				info.hitarea.onRollOver = function():Void {
					this._parent._parent.base.onRollOver();
				};
				info.hitarea.onRollOut = function():Void {
					this._parent._parent.base.onRollOut();
				};
				info.hitarea.onPress = function():Void {
					this._parent._parent.base.onPress();
				};
			}
			// Load picture.
			loadItemPic(mc, items[i]);
		}
		// Setup scrollbar.
		var isVisible:Boolean = (_viewModeIsMap)
			? (items.length > _COLS_PER_PAGE * _ROWS_PER_PAGE)
			: (items.length > _ROWS_PER_PAGE)
		;
		var scrollbar:ScrollBar = new ScrollBar(
			_gui,
			_clip.itemsBoard.scrollbar,
			itms,
			isVisible
		);
	}

	/**
	 * Load item pic
	 */
	 public function loadItemPic(clip:MovieClip, item:Object):Void {
		// Show loader animation while loading is in progress.
		var loaderAni:LoaderAnimation = new LoaderAnimation(clip.loader);
		var mclListener:Object = new Object();
		mclListener.loader = loaderAni;
		mclListener.onLoadProgress = function(
			target:MovieClip,
			bl:Number,
			bt:Number
		):Void {
			var mc:MovieClip = target._parent._parent;
			var p:Number = ((bt > 0) ? bl / bt * 100 : 0) >> 0;
			// Show percentages in the loader textfield.
			this.loader.setValue(p);
		};
		mclListener.onLoadInit = function(target:MovieClip):Void {
			var mc:MovieClip = target._parent._parent;
			// Stops the loader animation.
			this.loader.removeAnimation();
			// Fade in picture. 
			mc.pic._visible = true;
			mc.pic._alpha = 0;
			mc.pic.onEnterFrame = function():Void {
				if((this._alpha += 10) > 90) {
					this._alpha = 100;
					this._parent.loader._visible = false;
					delete this.onEnterFrame;
				}
			};
		};
		// Hide picture clip while loading is in progress.
		clip.pic._visible = false;
		// Create loader an attach listener object.
		var mcLoader:MovieClipLoader = new MovieClipLoader();
		mcLoader.addListener(mclListener);

		// *** crappy junk-hack ***
		// have to do it this way until the webservice is finished
		var image_url:String = item.image_url;
		image_url = image_url.split("size=big").join("size=medium");

		// Start loading.
		mclListener.loader.createAnimation();
		mcLoader.loadClip(image_url, clip.pic.con);
	}

	/*
	 * Transforms the gross.
	 * i.e. converts Number(16.9) to String("16,90")
	 */
	private static function transformGross(nGross:Number):String {
		var a:String = Math.round(nGross * 100).toString();
		return a.substring(0, a.length-2 ) + "," + a.substr(-2);
	}

}
